﻿using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.Configuration;
using PHMEE.DTOS.StatusMonitor;
using PHMEE.Entities.BaseInfo.Units;
using PHMEE.Entities.DaqInfo.TdDevices;
using PHMEE.IServices.StatusMonitor;
using PHMEE.PHM.Algorithms.Basic;
using PHMEE.TDengineInfrastructure;
using PHMEE.ToolKits;
using Scriban.Runtime.Accessors;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using TDengine.Data.Client;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Specifications;
using Volo.Abp.Uow;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using static PHMEE.Constants.PhmeeEnum;
using static PHMEE.PHMEEAdminPermissions;

namespace PHMEE.Services.StatusMonitor
{
    /// <summary>
    /// 设备状态监测
    /// </summary>
    public class UnitStatusMonitorAppService : PHMEEAppService, IUnitStatusMonitorAppService
    {
        private readonly TdEngineCommonAppService tdengineAppService;
        private readonly IPointRepository pointRepository;
        private readonly IVesselRepository vesselRepository;

        public UnitStatusMonitorAppService(TdEngineCommonAppService tdengineAppService, IPointRepository pointRepository, IVesselRepository vesselRepository)
        {
            this.tdengineAppService = tdengineAppService;
            this.pointRepository = pointRepository;
            this.vesselRepository = vesselRepository;
        }


        /// <summary>
        /// 获取机组集合相关信息
        /// </summary>
        /// <param name="vesselId"></param>
        /// <returns></returns>
        public async Task<List<UnitStatusTabModel>> GetUnitStatusTabs(Guid VesselId)
        {
            var list = new List<UnitStatusTabModel>();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            if (vessel != null)
            {
                var units = vessel.Units.OrderBy(item => item.Type).ThenBy(item => item.Number).ToList();

                foreach (var unit in units)
                {
                    UnitStatusTabModel model = new UnitStatusTabModel();

                    model.VesselId = vessel.Id;

                    model.VesselName = vessel.DisplayName;

                    model.UnitId = unit.Id;

                    model.UnitName = unit.DisplayName;

                    model.UnitNumber = unit.Number;

                    model.UnitType = unit.Type;

                    model.UnitTypeDescription = PHMEECoreHelper.PhmeeGetDescription(unit.Type);

                    list.Add(model);
                }
            }

            return list;
        }


        #region 主机机组

        /// <summary>
        /// 获取主机参数相关信息
        /// </summary>
        /// <param name="VesselId"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<UnitMainModel> GetUnitMainEngineMainParams(Guid VesselId, UnitBaseInput input)
        {
            var model = new UnitMainModel();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            var unit = vessel.GetUnit(input.UnitId, L) as MainEngineUnit;

            if (unit != null)
            {
                var equipment主机 = unit.Equipments.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == EquipmentEnum.MainEngine) as MainEngine;

                var equipment轴系 = unit.Equipments.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == EquipmentEnum.ShaftSystem) as ShaftSystem;

                var query = await pointRepository.PhmeeGetQuery();

                if (equipment主机 != null)
                {
                    equipment主机.DeserializeProperties();

                    model.MaxMainEnginePower = equipment主机.RatedPower;

                    var pointQuery = query.Where(new PointSpecificationEquipment(equipment主机.Id));

                    List<Point> points = pointQuery.ToList();

                    List<Point> points主轴承 = new List<Point>();

                    var component主轴承 = equipment主机.Components.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == ComponentEnum.MainBearComponent) as MainBearComponent;

                    if (component主轴承 != null)
                    {
                        var pointQuery主轴承 = query.Where(new PointSpecificationComponent(component主轴承.Id));

                        points主轴承 = pointQuery主轴承.ToList();

                    }

                    var point主机状态 = points.FirstOrDefault(item => item.Type == PointTypeEnum.MainEngineStatus && item.Tag == BaseInfoTagEnum.MainEngineStatus);

                    var point当前燃料类型 = points.FirstOrDefault(item => item.Type == PointTypeEnum.FuelType && item.Tag == BaseInfoTagEnum.FuelType);

                    var point主机功率 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Power && item.Tag == BaseInfoTagEnum.Power);

                    var point主机负荷 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Load && item.Tag == BaseInfoTagEnum.Load);

                    var point主机转速 = points.FirstOrDefault(item => item.Type == PointTypeEnum.RevSpeed && item.Tag == BaseInfoTagEnum.Speed);

                    var point主机即时油耗 = points.FirstOrDefault(item => item.Type == PointTypeEnum.FuelConsumption && item.Tag == BaseInfoTagEnum.Instant);

                    var point扫气压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.ScavenPres);

                    var point角度编码器 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Angle && item.Tag == BaseInfoTagEnum.AngleEncoder);

                    var point缸套冷却水进机压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.CylinderWaterInPres);

                    var point缸套冷却水进机温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.CylinderWaterInTemp);

                    var point扫气箱温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.ScavengeBoxTemp);

                    var point燃油进机压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.FuelOilInPresM);

                    var point燃油进机温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.FuelOilInTempM);


                    var point主机滑油进口压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.LubeOilInPres);

                    var point活塞冷却油进口压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.PistonCoolingOilInPres);

                    var point主机滑油进口温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.LubeOilInTemp);

                    var point活塞冷却油进口温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.PistonCoolingOilInTemp);

                    var point主轴承滑油进口压力 = points主轴承.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.LubeOilInPres);


                    var point进油粘度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Viscosity && item.Tag == BaseInfoTagEnum.OilInViscosity);

                    var point启动空气压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.StartUpAirPres);

                    var point排气平均温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.ExhaustAvgTemp);


                    await tdengineAppService.FetchTdEngineData(point主机状态, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrStatus = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.MainEngineStatusTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.MainEngineStatusOrg = tdengineAppService.GetTdEngineTypeValue<string>(reader, attrStatus);

                    });

                    await tdengineAppService.FetchTdEngineData(point当前燃料类型, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdFlowmeter.ts);

                        var attrFuelType = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdFlowmeter.FuelType);

                        model.FuelTypeTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.FuelTypeOrg = tdengineAppService.GetTdEngineTypeValue<int?>(reader, attrFuelType);

                    });

                    await tdengineAppService.FetchTdEngineData(point主机功率, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrPower = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.MainEnginePowerKwTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.MainEnginePowerKwOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrPower);

                    });

                    await tdengineAppService.FetchTdEngineData(point主机负荷, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrLoad = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.MainEngineLoadTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.MainEngineLoadOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrLoad);

                    });

                    await tdengineAppService.FetchTdEngineData(point主机转速, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrSpeed = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.MainEngineSpeedRpmTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.MainEngineSpeedRpmOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrSpeed);

                    });

                    await tdengineAppService.FetchTdEngineData(point主机即时油耗, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrInstant = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.MainEngineInstantTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.MainEngineInstantOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrInstant);

                    });

                    await tdengineAppService.FetchTdEngineData(point扫气压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrScavengePressure = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.ScavengePressureTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.ScavengePressureOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrScavengePressure);

                    });

                    await tdengineAppService.FetchTdEngineData(point角度编码器, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrEngineAngleEncoder = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.EngineAngleEncoderTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.EngineAngleEncoderOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrEngineAngleEncoder);

                    });

                    await tdengineAppService.FetchTdEngineData(point缸套冷却水进机压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrCylinderWaterInPressure = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.CylinderWaterInPressureTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.CylinderWaterInPressureOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrCylinderWaterInPressure);

                    });

                    await tdengineAppService.FetchTdEngineData(point缸套冷却水进机温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrCylinderWaterInTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.CylinderWaterInTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.CylinderWaterInTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrCylinderWaterInTemp);

                    });

                    await tdengineAppService.FetchTdEngineData(point扫气箱温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrScavengeBoxTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.ScavengeBoxTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.ScavengeBoxTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrScavengeBoxTemp);

                    });

                    await tdengineAppService.FetchTdEngineData(point燃油进机压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrFuelInPressure = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.FuelInPressureTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.FuelInPressureOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrFuelInPressure);

                    });

                    await tdengineAppService.FetchTdEngineData(point燃油进机温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrFuelInTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.FuelInTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.FuelInTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrFuelInTemp);

                    });

                    await tdengineAppService.FetchTdEngineData(point主机滑油进口压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrMainEngineLubeInPressure = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.MainEngineLubeInPressureTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.MainEngineLubeInPressureOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrMainEngineLubeInPressure);

                    });

                    await tdengineAppService.FetchTdEngineData(point活塞冷却油进口压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrPistonCoolingOilInPressure = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.PistonCoolingOilInPressureTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.PistonCoolingOilInPressureOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrPistonCoolingOilInPressure);

                    });

                    await tdengineAppService.FetchTdEngineData(point主机滑油进口温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrMainEngineLubeInTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.MainEngineLubeInTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.MainEngineLubeInTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrMainEngineLubeInTemp);

                    });

                    await tdengineAppService.FetchTdEngineData(point活塞冷却油进口温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrPistonCoolingOilInTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.PistonCoolingOilInTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.PistonCoolingOilInTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrPistonCoolingOilInTemp);

                    });

                    await tdengineAppService.FetchTdEngineData(point主轴承滑油进口压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrMainLubeInPressure = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.MainLubeInPressureTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.MainLubeInPressureOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrMainLubeInPressure);

                    });

                    await tdengineAppService.FetchTdEngineData(point进油粘度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrOilInViscosity = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.OilInViscosityTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.OilInViscosityOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrOilInViscosity);

                    });

                    await tdengineAppService.FetchTdEngineData(point启动空气压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrStartUpAirPres = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.StartUpAirPresTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.StartUpAirPresOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrStartUpAirPres);

                    });

                    await tdengineAppService.FetchTdEngineData(point排气平均温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrExhaustAvgTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.ExhaustAvgTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.ExhaustAvgTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrExhaustAvgTemp);

                    });

                }

                if (equipment轴系 != null)
                {
                    equipment轴系.DeserializeProperties();

                    var pointQuery = query.Where(new PointSpecificationEquipment(equipment轴系.Id));

                    List<Point> points = pointQuery.ToList();

                    List<Point> points推力轴承 = new List<Point>();

                    var component推力轴承 = equipment轴系.Components.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == ComponentEnum.ThrustBearComponent) as ThrustBearComponent;

                    if (component推力轴承 != null)
                    {
                        var pointQuery推力轴承 = query.Where(new PointSpecificationComponent(component推力轴承.Id));

                        points推力轴承 = pointQuery推力轴承.ToList();
                    }

                    var poin推力轴承滑油进口压力 = points推力轴承.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.LubeOilInPres);

                    var point推力轴承温度 = points推力轴承.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.Temperature);


                    await tdengineAppService.FetchTdEngineData(poin推力轴承滑油进口压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrThrustBearingLubeInPressure = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.ThrustBearingLubeInPressureTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.ThrustBearingLubeInPressureOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrThrustBearingLubeInPressure);

                    });

                    await tdengineAppService.FetchTdEngineData(point推力轴承温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrThrustBearingTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.ThrustBearingTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.ThrustBearingTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrThrustBearingTemp);

                    });

                }
            }

            return model;
        }

        /// <summary>
        /// 获取主机气缸状态参数相关信息
        /// </summary>
        /// <param name="VesselId"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<UnitCylinderModel>> GetUnitMainEngineCylinderParams(Guid VesselId, UnitBaseInput input)
        {
            List<UnitCylinderModel> list = new List<UnitCylinderModel>();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            var unit = vessel.GetUnit(input.UnitId, L) as MainEngineUnit;

            if (unit != null)
            {
                var equipment主机 = unit.Equipments.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == EquipmentEnum.MainEngine) as MainEngine;

                if (equipment主机 != null)
                {
                    List<Component> cylinders = equipment主机.Components.Where(item => item.Type == ComponentEnum.CylinderComponent).ToList();

                    var cylinderIds = cylinders.Select(item => item.Id).ToList();

                    var pointQuery = await pointRepository.PhmeeGetQuery();

                    pointQuery = pointQuery.Where(new PointSpecificationComponents(cylinderIds));

                    List<Point> pointsAll = pointQuery.ToList();

                    foreach (var cylinder in cylinders)
                    {
                        var points = pointsAll.Where(item => item.OwnerId == cylinder.Id).ToList();

                        var model = new UnitCylinderModel();

                        model.Id = cylinder.Id;

                        model.DisplayName = cylinder.DisplayName;

                        model.Number = cylinder.Number;

                        var point排气温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.ExhaustTemp);

                        var point冷却水出口温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.CoolantOutTemp);

                        var point活塞冷却油出口温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.PistonCoolOilOutTemp);

                        var point压缩压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.CompressPres);

                        var point爆压 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.BurstPres);

                        await tdengineAppService.FetchTdEngineData(point排气温度, input.DateTime, model, (reader, attributes, model) =>
                        {
                            var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                            var attrExhaustTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                            // 后续加上是否异常数据的获取赋值

                            model.ExhaustTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                            model.ExhaustTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrExhaustTemp);

                        });

                        await tdengineAppService.FetchTdEngineData(point冷却水出口温度, input.DateTime, model, (reader, attributes, model) =>
                        {
                            var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                            var attrCoolantOutTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                            // 后续加上是否异常数据的获取赋值

                            model.CoolantOutTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                            model.CoolantOutTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrCoolantOutTemp);

                        });

                        await tdengineAppService.FetchTdEngineData(point活塞冷却油出口温度, input.DateTime, model, (reader, attributes, model) =>
                        {
                            var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                            var attrPistonCoolOilOutTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                            // 后续加上是否异常数据的获取赋值

                            model.PistonCoolOilOutTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                            model.PistonCoolOilOutTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrPistonCoolOilOutTemp);

                        });

                        await tdengineAppService.FetchTdEngineData(point压缩压力, input.DateTime, model, (reader, attributes, model) =>
                        {
                            var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                            var attrCompressPres = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                            // 后续加上是否异常数据的获取赋值

                            model.CompressPresTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                            model.CompressPresOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrCompressPres);

                        });

                        await tdengineAppService.FetchTdEngineData(point爆压, input.DateTime, model, (reader, attributes, model) =>
                        {
                            var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                            var attrBurstPres = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                            // 后续加上是否异常数据的获取赋值

                            model.BurstPresTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                            model.BurstPresOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrBurstPres);

                        });

                        list.Add(model);
                    }
                }
            }

            return list;
        }

        /// <summary>
        /// 获取主机主轴承温度参数相关信息
        /// </summary>
        /// <param name="VesselId"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<UnitBearModel>> GetUnitMainEngineMainBearTemps(Guid VesselId, UnitBaseInput input)
        {
            List<UnitBearModel> list = new List<UnitBearModel>();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            var unit = vessel.GetUnit(input.UnitId, L) as MainEngineUnit;

            if (unit != null)
            {
                var equipment主机 = unit.Equipments.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == EquipmentEnum.MainEngine) as MainEngine;

                if (equipment主机 != null)
                {
                    List<Component> mainBears = equipment主机.Components.Where(item => item.Type == ComponentEnum.MainBearComponent).ToList();

                    var mainBearIds = mainBears.Select(item => item.Id).ToList();

                    var pointQuery = await pointRepository.PhmeeGetQuery();

                    pointQuery = pointQuery.Where(new PointSpecificationComponents(mainBearIds));

                    List<Point> pointsAll = pointQuery.ToList();

                    foreach (var mainBear in mainBears)
                    {
                        var points = pointsAll.Where(item => item.OwnerId == mainBear.Id).ToList();

                        var model = new UnitBearModel();

                        model.Id = mainBear.Id;

                        model.DisplayName = mainBear.DisplayName;

                        model.Number = mainBear.Number;

                        var point主轴承温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.Temperature);

                        await tdengineAppService.FetchTdEngineData(point主轴承温度, input.DateTime, model, (reader, attributes, model) =>
                        {
                            var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                            var attrTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                            model.TempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                            model.TempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrTemp);

                        });

                        list.Add(model);
                    }

                }
            }

            return list;
        }

        /// <summary>
        /// 获取主机增压器参数相关信息
        /// </summary>
        /// <param name="VesselId"></param>
        /// <param name="OnVessel"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<UnitTurboChargerModel>> GetUnitMainEngineTurboChargerParams(Guid VesselId, bool OnVessel, UnitBaseInput input)
        {
            List<UnitTurboChargerModel> list = new List<UnitTurboChargerModel>();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            var unit = vessel.GetUnit(input.UnitId, L) as MainEngineUnit;

            if (unit != null)
            {
                List<Equipment> turbochargers = unit.Equipments.Where(item => item.Type == EquipmentEnum.Turbocharger).OrderBy(item => item.Number).ToList();

                var turbochargerIds = turbochargers.Select(item => item.Id).ToList();

                var pointQuery = await pointRepository.PhmeeGetQuery();

                pointQuery = pointQuery.Where(new PointSpecificationEquipments(turbochargerIds));

                List<Point> pointsAll = pointQuery.ToList();

                foreach (var turbocharger in turbochargers)
                {
                    var points = pointsAll.Where(item => item.OwnerId == turbocharger.Id).ToList();

                    var model = new UnitTurboChargerModel();

                    model.Id = turbocharger.Id;

                    model.DisplayName = turbocharger.DisplayName;

                    model.Number = turbocharger.Number;

                    var point转速 = points.FirstOrDefault(item => item.Type == PointTypeEnum.RevSpeed && item.Tag == BaseInfoTagEnum.Speed);

                    var point滑油进口压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.LubeOilInPres);

                    var point增压器滑油出口压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.LubeOilOutPres);

                    var point增压器废气进口温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.ExhaustInTemp);

                    var point增压器废气出口温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.ExhaustOutTemp);

                    await tdengineAppService.FetchTdEngineData(point转速, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrSpeed = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.SpeedTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.SpeedOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrSpeed);

                    });

                    await tdengineAppService.FetchTdEngineData(point滑油进口压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrInletPressure = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.InletPressureTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.InletPressureOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrInletPressure);

                    });

                    await tdengineAppService.FetchTdEngineData(point增压器滑油出口压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrOutletPressure = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.OutletPressureTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.OutletPressureOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrOutletPressure);

                    });

                    await tdengineAppService.FetchTdEngineData(point增压器废气进口温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrEGInTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.EGInTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.EGInTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrEGInTemp);

                    });

                    await tdengineAppService.FetchTdEngineData(point增压器废气出口温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrEGOutTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.EGOutTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.EGOutTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrEGOutTemp);

                    });

                    list.Add(model);

                }

            }

            return list;
        }

        /// <summary>
        /// 获取主机测点相关信息
        /// </summary>
        /// <param name="VesselId"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<UnitPointModel>> GetUnitMainEnginePoints(Guid VesselId, UnitPointInput input)
        {
            List<UnitPointModel> unitPoints = new List<UnitPointModel>();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            var unit = vessel.GetUnit(input.UnitId, L);

            if (unit != null)
            {
                List<Guid> equipmentIds = unit.Equipments.Select(e => e.Id).ToList();

                List<Guid> componentIds = unit.Equipments.SelectMany(item => item.Components).Select(c => c.Id).ToList();

                var queryPoint = await pointRepository.PhmeeGetQuery();


                var queryUnitPoints = queryPoint.Where(item => item.Category == input.Category)
                                                .Where(item => item.OwnerId == unit.Id && item.OwnerType == nameof(Unit) ||
                                                               equipmentIds.Contains(item.OwnerId) && item.OwnerType == nameof(Equipment) ||
                                                               componentIds.Contains(item.OwnerId) && item.OwnerType == nameof(Component));

                List<Point> points = await AsyncExecuter.ToListAsync(queryUnitPoints);

                foreach (var point in points)
                {
                    var model = new UnitPointModel();

                    switch (point.OwnerType)
                    {
                        case nameof(Unit):

                            model.OwnerDisplayName = unit.DisplayName;

                            model.OwnerNumber = unit.Number;

                            model.OwnerSubType = unit.Type.ToString();

                            break;
                        case nameof(Equipment):

                            var ownerEquipment = unit.Equipments.FirstOrDefault(item => item.Id == point.OwnerId);

                            if (ownerEquipment != null)
                            {
                                model.OwnerDisplayName = ownerEquipment.DisplayName;

                                model.OwnerNumber = ownerEquipment.Number;

                                model.OwnerSubType = ownerEquipment.Type.ToString();

                            }

                            break;
                        case nameof(Component):

                            var ownerComponent = unit.Equipments.SelectMany(item => item.Components).FirstOrDefault(item => item.Id == point.OwnerId);

                            if (ownerComponent != null)
                            {
                                model.OwnerDisplayName = ownerComponent.DisplayName;

                                model.OwnerNumber = ownerComponent.Number;

                                model.OwnerSubType = ownerComponent.Type.ToString();

                            }

                            break;
                    }


                    model.PointId = point.Id;
                    model.PointName = point.DisplayName;
                    model.OwnerId = point.OwnerId;
                    model.OwnerType = point.OwnerType;
                    model.Category = point.Category;
                    model.Type = point.Type;
                    model.DerivedPropertiesJson = point.DerivedPropertiesJson;
                    model.TdFeatureData = await tdengineAppService.GetTdEnginePointFeatureDataNewest(VesselId, new TdFeatureInput() { PointId = point.Id, DateTime = input.DateTime });

                    unitPoints.Add(model);
                }
            }

            return unitPoints;
        }


        #endregion


        #region 主发电机机组

        /// <summary>
        /// 获取主发电机柴油机功率电流参数相关信息
        /// </summary>
        /// <param name="VesselId"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<UnitPowerCurrentModel> GetUnitMainGeneratorPowerCurrentParams(Guid VesselId, UnitBaseInput input)
        {
            var model = new UnitPowerCurrentModel();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            var unit = vessel.GetUnit(input.UnitId, L) as MainGeneratorUnit;

            if (unit != null)
            {
                var equipment柴油机 = unit.Equipments.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == EquipmentEnum.MainGeneratorDiesel) as MainGeneratorDiesel;

                var equipment发电机 = unit.Equipments.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == EquipmentEnum.MainGenerator) as MainGenerator;

                if (equipment柴油机 != null)
                {
                    equipment柴油机.DeserializeProperties();

                    model.MaxPower = equipment柴油机.RatedPower;

                    var pointQuery = await pointRepository.PhmeeGetQuery();

                    pointQuery = pointQuery.Where(new PointSpecificationEquipment(equipment柴油机.Id));

                    List<Point> points = pointQuery.ToList();

                    var point柴油机功率 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Power && item.Tag == BaseInfoTagEnum.Power);

                    await tdengineAppService.FetchTdEngineData(point柴油机功率, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrPower = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.PowerTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.PowerOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrPower);

                    });
                }

                if (equipment发电机 != null)
                {
                    equipment发电机.DeserializeProperties();

                    model.MaxCurrent = equipment发电机.RatedCurrent;

                    var pointQuery = await pointRepository.PhmeeGetQuery();

                    pointQuery = pointQuery.Where(new PointSpecificationEquipment(equipment发电机.Id));

                    List<Point> points = pointQuery.ToList();

                    var point发电机电流 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Current && item.Tag == BaseInfoTagEnum.Current);

                    await tdengineAppService.FetchTdEngineData(point发电机电流, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrCurrent = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.CurrentTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.CurrentOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrCurrent);

                    });

                }

            }

            return model;
        }

        /// <summary>
        /// 获取主发电机柴油机气缸状态参数相关信息
        /// </summary>
        /// <param name="VesselId"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<UnitCylinderModel>> GetUnitMainGeneratorDieselCylinderParams(Guid VesselId, UnitBaseInput input)
        {
            List<UnitCylinderModel> list = new List<UnitCylinderModel>();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            var unit = vessel.GetUnit(input.UnitId, L) as MainGeneratorUnit;

            if (unit != null)
            {
                var equipment柴油机 = unit.Equipments.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == EquipmentEnum.MainGeneratorDiesel) as MainGeneratorDiesel;

                if (equipment柴油机 != null)
                {
                    List<Component> cylinders = equipment柴油机.Components.Where(item => item.Type == ComponentEnum.CylinderComponent).ToList();

                    var cylinderIds = cylinders.Select(item => item.Id).ToList();

                    var pointQuery = await pointRepository.PhmeeGetQuery();

                    pointQuery = pointQuery.Where(new PointSpecificationComponents(cylinderIds));

                    List<Point> pointsAll = pointQuery.ToList();

                    foreach (var cylinder in cylinders)
                    {
                        var points = pointsAll.Where(item => item.OwnerId == cylinder.Id).ToList();

                        var model = new UnitCylinderModel();

                        model.Id = cylinder.Id;

                        model.DisplayName = cylinder.DisplayName;

                        model.Number = cylinder.Number;

                        var point排气温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.ExhaustTemp);

                        await tdengineAppService.FetchTdEngineData(point排气温度, input.DateTime, model, (reader, attributes, model) =>
                        {
                            var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                            var attrExhaustTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                            // 后续加上是否异常数据的获取赋值

                            model.ExhaustTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                            model.ExhaustTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrExhaustTemp);

                        });

                        list.Add(model);

                    }
                }
            }

            return list;
        }

        /// <summary>
        /// 获取主发电机柴油机图表状态参数相关信息
        /// </summary>
        /// <param name="VesselId"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<UnitDieselChartModel> GetUnitMainGeneratorDieselChartParams(Guid VesselId, UnitBaseInput input)
        {
            var model = new UnitDieselChartModel();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            var unit = vessel.GetUnit(input.UnitId, L) as MainGeneratorUnit;

            if (unit != null)
            {
                var equipment柴油机 = unit.Equipments.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == EquipmentEnum.MainGeneratorDiesel) as MainGeneratorDiesel;

                if (equipment柴油机 != null)
                {
                    var query = await pointRepository.PhmeeGetQuery();

                    var pointQuery = query.Where(new PointSpecificationEquipment(equipment柴油机.Id));

                    List<Point> points = pointQuery.ToList();

                    var point滑油进口压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.LubeOilInPres);

                    var point滑油进口温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.LubeOilInTemp);

                    var point冷却水进口压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.CoolantInPres);

                    var point冷却水出口温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.CoolantOutTemp);

                    var point燃油进机压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.FuelOilInPresM);

                    var point燃油进机温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.FuelOilInTempM);

                    await tdengineAppService.FetchTdEngineData(point滑油进口压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrLubeOilInPres = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.LubeOilInPresTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.LubeOilInPresOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrLubeOilInPres);

                    });

                    await tdengineAppService.FetchTdEngineData(point滑油进口温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrLubeOilInTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.LubeOilInTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.LubeOilInTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrLubeOilInTemp);

                    });

                    await tdengineAppService.FetchTdEngineData(point冷却水进口压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrCoolantInPres = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.CoolantInPresTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.CoolantInPresOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrCoolantInPres);

                    });

                    await tdengineAppService.FetchTdEngineData(point冷却水出口温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrCoolantOutTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.CoolantOutTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.CoolantOutTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrCoolantOutTemp);

                    });

                    await tdengineAppService.FetchTdEngineData(point燃油进机压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrFuelOilInPresM = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.FuelOilInPresMTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.FuelOilInPresMOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrFuelOilInPresM);

                    });

                    await tdengineAppService.FetchTdEngineData(point燃油进机温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrFuelOilInTempM = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.FuelOilInTempMTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.FuelOilInTempMOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrFuelOilInTempM);

                    });

                }
            }

            return model;
        }

        /// <summary>
        /// 获取主发电机柴油机主要参数相关信息
        /// </summary>
        /// <param name="VesselId"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<UnitGeneratorDieselMainModel> GetUnitMainGeneratorDieselMainParams(Guid VesselId, UnitBaseInput input)
        {
            var model = new UnitGeneratorDieselMainModel();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            var unit = vessel.GetUnit(input.UnitId, L) as MainGeneratorUnit;

            if (unit != null)
            {
                var equipment柴油机 = unit.Equipments.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == EquipmentEnum.MainGeneratorDiesel) as MainGeneratorDiesel;

                var equipment发电机 = unit.Equipments.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == EquipmentEnum.MainGenerator) as MainGenerator;

                if (equipment柴油机 != null)
                {
                    var pointQuery = await pointRepository.PhmeeGetQuery();

                    pointQuery = pointQuery.Where(new PointSpecificationEquipment(equipment柴油机.Id));

                    List<Point> points = pointQuery.ToList();

                    var point增压器转速 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Speed && item.Tag == BaseInfoTagEnum.ChargerSpeed);

                    var point扫气压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.ScavenPres);

                    var point滑油进机压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.LubeOilInPresM);

                    var point滑油进机温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.LubeOilInTempM);

                    var point排气总管温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.ExhaustTempT);

                    var point前轴承温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.FrontBearTemp);

                    var point高温淡水出机温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.HighOutTempM);

                    var point高温淡水进机压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.HighInPresM);


                    var point启动空气压力 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Pressure && item.Tag == BaseInfoTagEnum.StartUpAirPres);

                    var point涡轮排气出口温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.TurboExhaustOutTemp);

                    var point排气平均温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.ExhaustAvgTemp);



                    await tdengineAppService.FetchTdEngineData(point增压器转速, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrChargerSpeed = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.ChargerSpeedTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.ChargerSpeedOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrChargerSpeed);

                    });

                    await tdengineAppService.FetchTdEngineData(point扫气压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrScavenPres = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.ScavenPresTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.ScavenPresOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrScavenPres);

                    });

                    await tdengineAppService.FetchTdEngineData(point滑油进机压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrLubeOilInPresM = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.LubeOilInPresMTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.LubeOilInPresMOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrLubeOilInPresM);

                    });

                    await tdengineAppService.FetchTdEngineData(point滑油进机温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrLubeOilInPresM = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.LubeOilInPresMTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.LubeOilInPresMOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrLubeOilInPresM);

                    });

                    await tdengineAppService.FetchTdEngineData(point排气总管温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrExhaustTempT = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.ExhaustTempTTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.ExhaustTempTOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrExhaustTempT);

                    });

                    await tdengineAppService.FetchTdEngineData(point前轴承温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrFrontBearTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.FrontBearTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.FrontBearTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrFrontBearTemp);

                    });

                    await tdengineAppService.FetchTdEngineData(point高温淡水出机温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrHighOutTempM = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.HighOutTempMTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.HighOutTempMOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrHighOutTempM);

                    });

                    await tdengineAppService.FetchTdEngineData(point高温淡水进机压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrHighInPresM = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.HighInPresMTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.HighInPresMOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrHighInPresM);

                    });

                    await tdengineAppService.FetchTdEngineData(point启动空气压力, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrStartUpAirPres = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.StartUpAirPresTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.StartUpAirPresOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrStartUpAirPres);

                    });

                    await tdengineAppService.FetchTdEngineData(point涡轮排气出口温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrTurboExhaustOutTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.TurboExhaustOutTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.TurboExhaustOutTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrTurboExhaustOutTemp);

                    });

                    await tdengineAppService.FetchTdEngineData(point排气平均温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrExhaustAvgTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.ExhaustAvgTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.ExhaustAvgTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrExhaustAvgTemp);

                    });

                }

                if (equipment发电机 != null)
                {
                    var pointQuery = await pointRepository.PhmeeGetQuery();

                    pointQuery = pointQuery.Where(new PointSpecificationEquipment(equipment发电机.Id));

                    List<Point> points = pointQuery.ToList();

                    var point电压 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Voltage && item.Tag == BaseInfoTagEnum.Voltage);

                    var point有功功率 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Power && item.Tag == BaseInfoTagEnum.ActivePower);

                    var point无功功率 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Power && item.Tag == BaseInfoTagEnum.InActivePower);

                    var point视在功率 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Power && item.Tag == BaseInfoTagEnum.ApparentPower);

                    var point功率因数 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Power && item.Tag == BaseInfoTagEnum.PowerFactor);

                    var point频率 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Frequency && item.Tag == BaseInfoTagEnum.Frequency);




                    var point线圈温度RPH = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.RphCoilTemp);

                    var point线圈温度SPH = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.SphCoilTemp);

                    var point线圈温度TPH = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.TphCoilTemp);

                    await tdengineAppService.FetchTdEngineData(point电压, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrVoltage = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.VoltageTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.VoltageOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrVoltage);

                    });

                    await tdengineAppService.FetchTdEngineData(point有功功率, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrActivePower = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.ActivePowerTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.ActivePowerOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrActivePower);

                    });

                    await tdengineAppService.FetchTdEngineData(point无功功率, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrInActivePower = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.InActivePowerTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.InActivePowerOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrInActivePower);

                    });

                    await tdengineAppService.FetchTdEngineData(point视在功率, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrApparentPower = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.ApparentPowerTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.ApparentPowerOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrApparentPower);

                    });

                    await tdengineAppService.FetchTdEngineData(point功率因数, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrPowerFactor = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.PowerFactorTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.PowerFactorOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrPowerFactor);

                    });

                    await tdengineAppService.FetchTdEngineData(point频率, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrFrequency = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.FrequencyTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.FrequencyOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrFrequency);

                    });

                    await tdengineAppService.FetchTdEngineData(point线圈温度RPH, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrRphCoilTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.RphCoilTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.RphCoilTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrRphCoilTemp);

                    });

                    await tdengineAppService.FetchTdEngineData(point线圈温度SPH, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrSphCoilTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.SphCoilTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.SphCoilTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrSphCoilTemp);

                    });

                    await tdengineAppService.FetchTdEngineData(point线圈温度TPH, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrTphCoilTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.TphCoilTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.TphCoilTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrTphCoilTemp);

                    });

                }
            }

            return model;
        }

        /// <summary>
        /// 获取主发电机柴油机测点相关信息
        /// </summary>
        /// <param name="VesselId"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<UnitPointModel>> GetUnitMainGeneratorPoints(Guid VesselId, UnitPointInput input)
        {
            List<UnitPointModel> unitPoints = new List<UnitPointModel>();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            var unit = vessel.GetUnit(input.UnitId, L) as MainGeneratorUnit;

            if (unit != null)
            {
                List<Guid> equipmentIds = unit.Equipments.Select(e => e.Id).ToList();

                List<Guid> componentIds = unit.Equipments.SelectMany(item => item.Components).Select(c => c.Id).ToList();

                var queryPoint = await pointRepository.PhmeeGetQuery();


                var queryUnitPoints = queryPoint.Where(item => item.Category == input.Category)
                                                .Where(item => item.OwnerId == unit.Id && item.OwnerType == nameof(Unit) ||
                                                               equipmentIds.Contains(item.OwnerId) && item.OwnerType == nameof(Equipment) ||
                                                               componentIds.Contains(item.OwnerId) && item.OwnerType == nameof(Component));

                List<Point> points = await AsyncExecuter.ToListAsync(queryUnitPoints);

                foreach (var point in points)
                {
                    var model = new UnitPointModel();

                    switch (point.OwnerType)
                    {
                        case nameof(Unit):

                            model.OwnerDisplayName = unit.DisplayName;

                            model.OwnerNumber = unit.Number;

                            model.OwnerSubType = unit.Type.ToString();

                            break;
                        case nameof(Equipment):

                            var ownerEquipment = unit.Equipments.FirstOrDefault(item => item.Id == point.OwnerId);

                            if (ownerEquipment != null)
                            {
                                model.OwnerDisplayName = ownerEquipment.DisplayName;

                                model.OwnerNumber = ownerEquipment.Number;

                                model.OwnerSubType = ownerEquipment.Type.ToString();

                            }

                            break;
                        case nameof(Component):

                            var ownerComponent = unit.Equipments.SelectMany(item => item.Components).FirstOrDefault(item => item.Id == point.OwnerId);

                            if (ownerComponent != null)
                            {
                                model.OwnerDisplayName = ownerComponent.DisplayName;

                                model.OwnerNumber = ownerComponent.Number;

                                model.OwnerSubType = ownerComponent.Type.ToString();

                            }

                            break;
                    }


                    model.PointId = point.Id;
                    model.PointName = point.DisplayName;
                    model.OwnerId = point.OwnerId;
                    model.OwnerType = point.OwnerType;
                    model.Category = point.Category;
                    model.Type = point.Type;
                    model.DerivedPropertiesJson = point.DerivedPropertiesJson;
                    model.TdFeatureData = await tdengineAppService.GetTdEnginePointFeatureDataNewest(VesselId, new TdFeatureInput() { PointId = point.Id, DateTime = input.DateTime });

                    unitPoints.Add(model);
                }
            }

            return unitPoints;
        }


        #endregion


        #region 压载泵机组

        /// <summary>
        /// 获取压载泵功率电流参数相关信息
        /// </summary>
        /// <param name="VesselId"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<UnitPowerCurrentModel> GetUnitBallastPumpPowerCurrentParams(Guid VesselId, UnitBaseInput input)
        {
            var model = new UnitPowerCurrentModel();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            var unit = vessel.GetUnit(input.UnitId, L) as BallastPumpUnit;

            if (unit != null)
            {
                var equipment电动机 = unit.Equipments.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == EquipmentEnum.AsynElectricMotor) as AsynElectricMotor;

                if (equipment电动机 != null)
                {
                    equipment电动机.DeserializeProperties();

                    model.MaxPower = equipment电动机.RatedPower;

                    model.MaxCurrent = equipment电动机.RatedCurrent;

                    var pointQuery = await pointRepository.PhmeeGetQuery();

                    pointQuery = pointQuery.Where(new PointSpecificationEquipment(equipment电动机.Id));

                    List<Point> points = pointQuery.ToList();

                    var point电动机功率 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Power && item.Tag == BaseInfoTagEnum.Power);

                    var point电动机电流 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Current && item.Tag == BaseInfoTagEnum.Current);

                    await tdengineAppService.FetchTdEngineData(point电动机功率, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrPower = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.PowerTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.PowerOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrPower);

                    });

                    await tdengineAppService.FetchTdEngineData(point电动机电流, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrCurrent = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.CurrentTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.CurrentOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrCurrent);

                    });

                }
            }

            return model;
        }

        /// <summary>
        /// 获取压载泵参数相关信息
        /// </summary>
        /// <param name="VesselId"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<UnitBallastPumpMainModel> GetUnitBallastPumpMainParams(Guid VesselId, UnitBaseInput input)
        {
            var model = new UnitBallastPumpMainModel();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            var unit = vessel.GetUnit(input.UnitId, L) as BallastPumpUnit;

            if (unit != null)
            {
                var equipment电动机 = unit.Equipments.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == EquipmentEnum.AsynElectricMotor) as AsynElectricMotor;

                var equipment泵 = unit.Equipments.OrderBy(item => item.Number).FirstOrDefault(item => item.Type == EquipmentEnum.CentrifugalPump) as CentrifugalPump;

                if (equipment电动机 != null)
                {
                    var pointQuery = await pointRepository.PhmeeGetQuery();

                    pointQuery = pointQuery.Where(new PointSpecificationEquipment(equipment电动机.Id));

                    List<Point> points = pointQuery.ToList();

                    var point电动机转速 = points.FirstOrDefault(item => item.Type == PointTypeEnum.RevSpeed && item.Tag == BaseInfoTagEnum.Speed);

                    var point电动机驱动端温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.MotorDriveTemp);

                    var point电动机自由端温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.MotorNonDriveTemp);

                    await tdengineAppService.FetchTdEngineData(point电动机转速, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrSpeed = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.SpeedTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.SpeedOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrSpeed);

                    });

                    await tdengineAppService.FetchTdEngineData(point电动机驱动端温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attMotorDriveTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.MotorDriveTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.MotorDriveTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attMotorDriveTemp);

                    });

                    await tdengineAppService.FetchTdEngineData(point电动机自由端温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrMotorNonDriveTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.MotorNonDriveTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.MotorNonDriveTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrMotorNonDriveTemp);

                    });


                }

                if (equipment泵 != null)
                {
                    var pointQuery = await pointRepository.PhmeeGetQuery();

                    pointQuery = pointQuery.Where(new PointSpecificationEquipment(equipment泵.Id));

                    List<Point> points = pointQuery.ToList();

                    var point泵温度 = points.FirstOrDefault(item => item.Type == PointTypeEnum.Temperature && item.Tag == BaseInfoTagEnum.PumpTemp);

                    await tdengineAppService.FetchTdEngineData(point泵温度, input.DateTime, model, (reader, attributes, model) =>
                    {
                        var attrTs = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.ts);

                        var attrPumpTemp = attributes.FirstOrDefault(item => item.Name == PhmeeConst.TdAmsAnalog.Value);

                        model.PumpTempTs = tdengineAppService.GetTdEngineTypeValue<DateTime>(reader, attrTs);

                        model.PumpTempOrg = tdengineAppService.GetTdEngineTypeValue<float?>(reader, attrPumpTemp);

                    });

                }

            }

            return model;
        }

        /// <summary>
        /// 获取压载泵测点相关信息
        /// </summary>
        /// <param name="VesselId"></param>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<UnitPointModel>> GetUnitBallastPumpPoints(Guid VesselId, UnitPointInput input)
        {
            List<UnitPointModel> unitPoints = new List<UnitPointModel>();

            var vessel = await vesselRepository.PhmeeGetById(VesselId);

            var unit = vessel.GetUnit(input.UnitId, L) as BallastPumpUnit;

            if (unit != null)
            {
                List<Guid> equipmentIds = unit.Equipments.Select(e => e.Id).ToList();

                List<Guid> componentIds = unit.Equipments.SelectMany(item => item.Components).Select(c => c.Id).ToList();

                var queryPoint = await pointRepository.PhmeeGetQuery();


                var queryUnitPoints = queryPoint.Where(item => item.Category == input.Category)
                                                .Where(item => item.OwnerId == unit.Id && item.OwnerType == nameof(Unit) ||
                                                               equipmentIds.Contains(item.OwnerId) && item.OwnerType == nameof(Equipment) ||
                                                               componentIds.Contains(item.OwnerId) && item.OwnerType == nameof(Component));

                List<Point> points = await AsyncExecuter.ToListAsync(queryUnitPoints);

                foreach (var point in points)
                {
                    var model = new UnitPointModel();

                    switch (point.OwnerType)
                    {
                        case nameof(Unit):

                            model.OwnerDisplayName = unit.DisplayName;

                            model.OwnerNumber = unit.Number;

                            model.OwnerSubType = unit.Type.ToString();

                            break;
                        case nameof(Equipment):

                            var ownerEquipment = unit.Equipments.FirstOrDefault(item => item.Id == point.OwnerId);

                            if (ownerEquipment != null)
                            {
                                model.OwnerDisplayName = ownerEquipment.DisplayName;

                                model.OwnerNumber = ownerEquipment.Number;

                                model.OwnerSubType = ownerEquipment.Type.ToString();

                            }

                            break;
                        case nameof(Component):

                            var ownerComponent = unit.Equipments.SelectMany(item => item.Components).FirstOrDefault(item => item.Id == point.OwnerId);

                            if (ownerComponent != null)
                            {
                                model.OwnerDisplayName = ownerComponent.DisplayName;

                                model.OwnerNumber = ownerComponent.Number;

                                model.OwnerSubType = ownerComponent.Type.ToString();

                            }

                            break;
                    }


                    model.PointId = point.Id;
                    model.PointName = point.DisplayName;
                    model.OwnerId = point.OwnerId;
                    model.OwnerType = point.OwnerType;
                    model.Category = point.Category;
                    model.Type = point.Type;
                    model.DerivedPropertiesJson = point.DerivedPropertiesJson;
                    model.TdFeatureData = await tdengineAppService.GetTdEnginePointFeatureDataNewest(VesselId, new TdFeatureInput() { PointId = point.Id, DateTime = input.DateTime });

                    unitPoints.Add(model);
                }
            }

            return unitPoints;
        }


        #endregion
    }
}
